import axios from 'axios'
import qs from "qs";
import { config } from './config.js';
import { globalModal } from "@/data"
import errorCode from "./errorCode.js"
import { message, Modal } from 'antd'
/**@description 获取token */
const getAccessToken = () => {
    return sessionStorage.token
}
const getRefreshToken = () => { }
const getTenantId = () => { }
const removeToken = () => { }
const setToken = () => { }
const resetRouter = () => { };
const deleteUserCache = () => { };
const tenantEnable = true;
const { result_code, base_url, request_timeout } = config
// 需要忽略的提示。忽略后，自动 Promise.reject('error')
const ignoreMsgs = [
    '无效的刷新令牌', // 刷新令牌被删除时，不用提示
    '刷新令牌已过期' // 使用刷新令牌，刷新获取新的访问令牌时，结果因为过期失败，此时需要忽略。否则，会导致继续 401，无法跳转到登出界面
]
// 是否显示重新登录
export const isRelogin = { show: false };
//请求队列
let requestList = [];
// 是否正在刷新中
let isRefreshToken = false
// 请求白名单，无须token的接口
const whiteList = ['/login', '/refresh-token']
// 创建axios实例
const service = axios.create({
    baseURL: base_url, // api 的 base_url
    timeout: request_timeout, // 请求超时时间
    withCredentials: false // 禁用 Cookie 等信息
})
//request请求拦截器
service.interceptors.request.use(
    config => {
        //是否需要设置token
        let isToken = (config?.headers || {}).isToken === false;
        whiteList.some(v => {
            if (config.url) {
                config.url.indexOf(v) > -1
                return (isToken = false);
            }
        })
        if (getAccessToken && !isToken) {
            config.headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token

        }
        //设置租户
        if (tenantEnable && tenantEnable === true) {
            const tenantId = getTenantId();
            if (tenantId) {
                config.headers["tenant-id"] = tenantId;
            }
        }

        const params = config.params || {};
        const data = config.data || false;
        if (config.method.toUpperCase() === "POST" && config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
            config.data = qs.stringify(data);
        }
        //get 参数解码
        if (config.method.toUpperCase() === "GET" && params) {
            config.params = {};
            const paramsStr = qs.stringify(params, { allowDots: true });
            if (paramsStr) {
                config.url = config.url + "?" + paramsStr;
            }
        }
        return config;
    },
    error => {
        return Promise.reject(error)
    }
)
//响应拦截器
service.interceptors.response.use(
    async (response) => {
        let { data } = response;
        let config = response.config;
        if (!data) {
            //如果没有数据， 返回一个报错
            throw new Error();
        }

        //二进制数据则直接返回，例如excel导出
        if (
            response.request.responseType === 'blob' ||
            response.request.responseType === 'arraybuffer'
        ) {
            // 注意：如果导出的响应为 json，说明可能失败了，不直接返回进行下载
            if (response.data.type !== 'application/json') {
                return response.data
            }
            data = await new Response(response.data).json()
        }

        const code = data.code || result_code
        // 获取错误信息
        const msg = data.msg || errorCode[code] || errorCode['default']
        if (ignoreMsgs.indexOf(msg) !== -1) {
            //如果是忽略的错误码，直接返回msg异常
            return Promise.reject(msg);
        } else if (code === 401) {
            //如果未认证 且 未进行刷新token，可能是token过期了
            if (!isRefreshToken) {
                isRefreshToken = true;
                //如果获取不到新token，就退出登录
                if (!getRefreshToken()) {
                    return handleAuthorized();
                }
                //否则 刷新token
                // try {
                //     const refreshTokenRes = await refreshToken();
                //     //刷新成功
                //     setToken(refreshTokenRes.data.data);
                //     config.headers?.Authorization = "Bearer " + getAccessToken();
                //     requestList.forEach((cb) => {
                //         cb();
                //     })
                //     requestList = [];
                //     return service(config);
                // } catch (error) {
                //     // 为什么需要 catch 异常呢？刷新失败时，请求因为 Promise.reject 触发异常。
                //     // 2.2 刷新失败，只回放队列的请求
                //     requestList.forEach((fun) => {
                //         fun();
                //     })
                //     // 提示是否要登出。即不回放当前请求！不然会形成递归
                //     return handleAuthorized()
                // } finally {
                //     requestList = []
                //     isRefreshToken = false
                // }
            } else {
                //添加到队列 等待刷新获取到新的token
                // return new Promise(resolve => {
                //     requestList.push(() => {
                //         config?.headers?.Authorization = "Bearer " + getAccessToken();
                //         resolve(service(config));
                //     })
                // })
            }
        } else if (code === 500) {
            message.error("服务器报500错误");
            return Promise.reject(new Error(msg));
        } else if (code === 901) {
            message.error("自定义其他错误");
            return Promise.reject(new Error(msg));
        } else if (code !== 200) {
            if (msg === '无效的刷新令牌') {
                // hard coding：忽略这个提示，直接登出
                console.log(msg)
                return handleAuthorized()
            } else {
                message.error(msg);
                globalModal.methods.modal.error({
                    title: '错误提示',
                    content: msg,
                    okText: '确认',
                    centered: true,
                });
            }
            return Promise.reject('error')
        } else {
            // console.log("检测通过，返回data", data)
            // return Promise.resolve(data);
            return data;
        }
    },
    error => {
        console.log('响应拦截器错误：' + error) // for debug
        let { message } = error;
        if (message === "Network Error") {
            message = "网络错误";
        } else if (message.includes("timeout")) {
            message = "请求超时";
        } else if (message.includes('Request failed with status code')) {
            message = "状态码出错";
        }
        globalModal.methods.modal.error({
            title: '错误提示',
            content: message,
            okText: '确认',
            centered: true,
        });
        return Promise.reject(error)
    }
)

/**@description 登出操作 */
const handleAuthorized = () => {

}

/**@description 刷新token */
const refreshToken = async () => {
    // axios.defaults.headers.common['tenant-id'] = getTenantId()
    // return await axios.post(base_url + '/system/auth/refresh-token?refreshToken=' + getRefreshToken())
}

export { service }